﻿//-----------------------------------------------------------------------
// <copyright>
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
// </copyright>
//----------------------------------------------------------------------- 
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;

namespace Fulcrum.ControlGenerator
{
    public enum PropertyVisibility
    {
        Public,
        Private
    }

    public class DependencyPropertyDataContext : IDependencyPropertyDataContext
    {
        ICollection<string> metadataOptions;

        public DependencyPropertyDataContext(IDependencyPropertyConfiguration config)
        {
            this.CoerceValue = config.CoerceValue;
            this.DefaultValue = config.DefaultValue;
            this.Description = config.Description;
            this.IsReadOnly = config.IsReadOnly;
            this.TypeConverter = config.TypeConverter;
            this.LocalizationCategory = config.LocalizationCategory;
            this.LocalizationModifiability = config.LocalizationModifiability;
            this.LocalizationReadability = config.LocalizationReadability;

            this.SetMetadataOptions(config.MetadataOptions);

            this.Name = config.Name;
            this.ProvideSetter = config.ProvideSetter;
            this.Remarks = config.Remarks;
            this.Summary = config.Summary;
            this.Type = config.Type;
            this.ValidateValue = config.ValidateValue;
            this.Visibility = config.Visibility;
        }

        public string Name
        {
            get;
            private set;
        }

        public string Type
        {
            get;
            private set;
        }

        public string DefaultValue
        {
            get;
            private set;
        }

        public bool IsReadOnly
        {
            get;
            private set;
        }

        public PropertyVisibility Visibility
        {
            get;
            private set;
        }

        public bool CoerceValue
        {
            get;
            private set;
        }

        public bool ValidateValue
        {
            get;
            private set;
        }

        public ICollection<string> MetadataOptions
        {
            get
            {
                return this.metadataOptions;
            }
        }

        void SetMetadataOptions(ICollection<string> options)
        {
            var innerOptions = new List<string>(options);
            this.metadataOptions = new ReadOnlyCollection<string>(innerOptions);
        }

        public string DependencyPropertyName
        {
            get
            {
                return String.Format("{0}Property", this.Name);
            }
        }

        public string DependencyPropertyKeyName
        {
            get
            {
                Debug.Assert(this.IsReadOnly);
                return String.Format("{0}PropertyKey", this.Name);
            }
        }

        public string StaticChangedMethodName
        {
            get
            {
                return String.Format("{0}_PropertyChanged", this.DependencyPropertyName);
            }
        }

        public string StaticCoerceMethodName
        {
            get
            {
                return String.Format("{0}_CoerceProperty", this.DependencyPropertyName);
            }
        }

        public string StaticValidateMethodName
        {
            get
            {
                return String.Format("{0}_ValidateProperty", this.DependencyPropertyName);
            }
        }

        public string StaticPartialValidateMethodName
        {
            get
            {
                return String.Format("{0}_ValidatePropertyImplementation", this.DependencyPropertyName);
            }
        }

        public string Summary
        {
            get;
            private set;
        }

        public string Remarks
        {
            get;
            private set;
        }

        public string Description
        {
            get;
            private set;
        }

        /// <summary>
        /// This is needed because a RO dependency property which is a collection can't be have items
        /// provided to it via XAML if there is a setter (even if it is private).
        /// This appears to be an issue w/ the compiler/XAML engine.
        /// </summary>
        public bool ProvideSetter
        {
            get;
            private set;
        }

        public LocalizationCategory LocalizationCategory
        {
            get;
            private set;
        }

        public Modifiability LocalizationModifiability
        {
            get;
            private set;
        }

        public Readability LocalizationReadability
        {
            get;
            private set;
        }

        public string ChangedMethodName
        {
            get
            {
                return String.Format("On{0}Changed", this.Name);
            }
        }

        public string CoerceMethodName
        {
            get
            {
                return String.Format("OnCoerce{0}", this.DependencyPropertyName);
            }
        }

        public string EventName
        {
            get
            {
                return String.Format("{0}Changed", this.Name);
            }
        }

        public string RoutedEventName
        {
            get
            {
                return String.Format("{0}Event", this.EventName);
            }
        }

        public string TypeConverter
        {
            get;
            private set;
        }
    }
}
